using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using PowerfulExtensions.Helpers;

namespace PowerfulExtensions.Linq
{
    public static class LinqExtensions
    {
        public static void Foreach<TClass>(this IEnumerable<TClass> collection, Action<TClass> action)
        {
            foreach (var element in collection)
            {
                action(element);
            }    
        }

        public static IEnumerable<TClass> Distinct<TClass>(this IEnumerable<TClass> collection, params Expression<Func<TClass, object>>[] expressions)
        {
            var distinct = collection.Distinct(new ByMembersEqualityComparer<TClass>(expressions));
            return distinct;
        }

        public static IEnumerable<TClass> Union<TClass>(this IEnumerable<TClass> collectionA, IEnumerable<TClass> collectionB, params Expression<Func<TClass, object>>[] expressions)
        {
            var union = collectionA.Matherialize().Union(collectionB.Matherialize(), new ByMembersEqualityComparer<TClass>(expressions));
            return union;
        }

        public static IEnumerable<TClass> Intersect<TClass>(this IEnumerable<TClass> collectionA, IEnumerable<TClass> collectionB, params Expression<Func<TClass, object>>[] expressions)
        {
            var intersect = collectionA.Intersect(collectionB, new ByMembersEqualityComparer<TClass>(expressions));
            return intersect;
        }

        public static IEnumerable<TClass> Except<TClass>(this IEnumerable<TClass> collectionA, IEnumerable<TClass> collectionB, params Expression<Func<TClass, object>>[] expressions)
        {
            var except = collectionA.Except(collectionB, new ByMembersEqualityComparer<TClass>(expressions));
            return except;
        }

        public static IEnumerable<TClass> Matherialize<TClass>(this IEnumerable<TClass> collection)
        {
            return collection as ICollection<TClass> ?? collection.ToArray();  
        } 
    }
}
